﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Navigation;
using System.Threading;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace SZ_OEMHost
{    
    public partial class MainWindow : Window
    {
        //////////////////////////////////////////////////////////////////////////
        // Member Variables

        // Common Variables
        public bool                m_bConModeIsUSB = false;                // Default is COM
        public object              m_objSender;
        public RoutedEventArgs     m_argEvent;
        byte[]              m_pTemplateData = new byte[CommonDefine.GD_RECORD_SIZE];
        byte[]              m_pTemplateData2 = new byte[CommonDefine.GD_RECORD_SIZE];
        bool                m_bParamGet = false;

        // Serial
        enum BAUD_RATE_Ndx
        {
            BAUD9600 = 0,
            BAUD19200 = 1,
            BAUD38400 = 2,
            BAUD57600 = 3,
            BAUD115200 = 4
        };
        uint[]              m_pBaudRates = new uint[5];
        public static SerialCom           m_clsSerial;

        // USB
        public static USBComm             m_clsUSB;

        // Command
        public static CommandProc         m_clsCmdProc;
        int                 m_nCmdIndex = 0;
        enum COMMAND_NDX
        {
            CMD_ENROLL = 0,
            CMD_VERIFY,
            CMD_IDENTIFY,
            CMD_IDENTIFY_FREE,
            CMD_ENROLL_ONETIME,
            CMD_CHANGE_TEMPLATE,
            CMD_CLEAR_TEMPLATE,
            CMD_CLEAR_ALLTEMPLATE,
            CMD_GET_EMPTY_ID,
            CMD_GET_BROKEN_TEMPLATE,
            CMD_READ_TEMPLATE,
            CMD_WRITE_TEMPLATE,
            CMD_SET_PARAMETER,
            CMD_GET_FW_VERSION,
            CMD_FINGER_DETECT,
            CMD_FEATURE_OF_CAPTURED_FP,
            CMD_IDENTIFY_WITH_TMPL,
            CMD_SET_DEVPASS,
            CMD_VERIFY_DEVPASS,
            CMD_EXIT_DEVPASS,
            CMD_GET_ENROLL_COUNT,
            CMD_UP_IMAGE,
            CMD_IDENTIFY_WITH_DOWN_IMAGE,
            CMD_VERIFY_WITH_DOWN_IMAGE,
            CMD_IDENTIFY_WITH_DOWN_TMPL,
            CMD_VERIFY_WITH_DOWN_TMPL,
            CMD_ADJUST_SENSOR,
            CMD_ENTER_ISPMODE,
            CMD_FP_CANCEL,
        };
        struct ST_COMMAND
        {
            private readonly string w_strCmdName;
            private readonly int w_nCode;

            public ST_COMMAND(string p_strCmdName, int p_nCode)
            {
                this.w_strCmdName = p_strCmdName;
                this.w_nCode = p_nCode;
            }

            public string m_strCmdName{ get { return w_strCmdName; } }
            public int m_nCode{ get { return w_nCode; } }
        }
        static ST_COMMAND[] m_pCmd = new ST_COMMAND[] {
            new ST_COMMAND("按三次手指注册指纹",                            CommonDefine.CMD_ENROLL_CODE),
            new ST_COMMAND("1:1比对",										CommonDefine.CMD_VERIFY_CODE),
	        new ST_COMMAND("1:N比对",										CommonDefine.CMD_IDENTIFY_CODE),
	        new ST_COMMAND("连续1:N比对",									CommonDefine.CMD_IDENTIFY_FREE_CODE),
	        new ST_COMMAND("按一次手指注册指纹",							CommonDefine.CMD_ENROLL_ONETIME_CODE),
	        new ST_COMMAND("注册并替换指定指纹",							CommonDefine.CMD_CHANGE_TEMPLATE_CODE),
	        new ST_COMMAND("指定删除指纹",								    CommonDefine.CMD_CLEAR_TEMPLATE_CODE),
	        new ST_COMMAND("全部删除指纹",							        CommonDefine.CMD_CLEAR_ALLTEMPLATE_CODE),
	        new ST_COMMAND("获取最小空ID",									CommonDefine.CMD_GET_EMPTY_ID_CODE),
	        new ST_COMMAND("检查无效指纹ID",							    CommonDefine.CMD_GET_BROKEN_TEMPLATE_CODE),
	        new ST_COMMAND("取出指定的指纹数据",							CommonDefine.CMD_READ_TEMPLATE_CODE),
	        new ST_COMMAND("写入指定的指纹数据",							CommonDefine.CMD_WRITE_TEMPLATE_CODE),
	        new ST_COMMAND("参数设置",									    CommonDefine.CMD_SET_PARAMETER_CODE),
	        new ST_COMMAND("获取固件版本",								    CommonDefine.CMD_GET_FW_VERSION_CODE),
	        new ST_COMMAND("检测指纹是否按下",								CommonDefine.CMD_FINGER_DETECT_CODE),
	        new ST_COMMAND("获取按下手指的数据",				            CommonDefine.CMD_FEATURE_OF_CAPTURED_FP_CODE),
	        new ST_COMMAND("按下手指和输入的指纹数据比对",	                CommonDefine.CMD_IDENTIFY_TEMPLATE_WITH_FP_CODE),
	        new ST_COMMAND("设置通讯密码",							        CommonDefine.CMD_SET_DEVPASS_CODE),
	        new ST_COMMAND("校验通讯密码",						            CommonDefine.CMD_VERIFY_DEVPASS_CODE),
	        new ST_COMMAND("启用通讯密码",							        CommonDefine.CMD_EXIT_DEVPASS_CODE),
	        new ST_COMMAND("获取注册的指纹数量",							CommonDefine.CMD_GET_ENROLL_COUNT_CODE),
	        new ST_COMMAND("采集指纹图像",									CommonDefine.CMD_UP_IMAGE_CODE),
	        new ST_COMMAND("指纹图像1：N比对",				                CommonDefine.CMD_IDENTIFY_WITH_IMAGE_CODE),
	        new ST_COMMAND("指纹图像1：1比对",					            CommonDefine.CMD_VERIFY_WITH_IMAGE_CODE),
	        new ST_COMMAND("指纹模板1：N比对",				                CommonDefine.CMD_IDENTIFY_WITH_DOWN_TMPL_CODE),
	        new ST_COMMAND("指纹模板1：1比对",				                CommonDefine.CMD_VERIFY_WITH_DOWN_TMPL_CODE),
	        new ST_COMMAND("校准传感器",									CommonDefine.CMD_ADJUST_SENSOR_CODE),
	        new ST_COMMAND("清空固件！",								    CommonDefine.CMD_ENTER_ISPMODE_CODE)
        };

        static string[] m_pStrParamMode = new string[] {
            "读取",
            "写入"
        };

        static string[] m_pStrParamIndex = new string[] {
            "设备编号",
            "安全级别",
            "重复检查",
            "波特率",
            "自学习",
            "超时时间",
            "工作模式"
        };
        //////////////////////////////////////////////////////////////////////////

        public MainWindow()
        {
            // Init Classes
            m_clsCmdProc = new CommandProc(this);
            m_clsSerial = new SerialCom();
            m_clsUSB = new USBComm(this);

            // Initialize Control
            InitializeComponent();

            // Init COMPort Control
            InitCOMPort();

            // Init Command Control
            InitCommandControl();

            // Set Control State
            SetControlState(false); // Not Connected
        }

        public void InitCOMPort()
        {
            int w_nI;
            int w_nCOMCount;
            List<string> w_aCOMPort;

            // Get Available COM Port
            cmbCI_COMPort.Items.Clear();
            w_aCOMPort = m_clsSerial.GetAllPorts();
            w_nCOMCount = w_aCOMPort.Count();
            for (w_nI = 0; w_nI < w_nCOMCount; w_nI ++)
            {
                ComboBoxItem w_cbiItem = new ComboBoxItem();
                w_cbiItem.Content = w_aCOMPort.ElementAt(w_nI);
                cmbCI_COMPort.Items.Add(w_cbiItem);
            }
            cmbCI_COMPort.SelectedIndex = 0;

            // Init Baudrate Values
            m_pBaudRates[0] = 9600; m_pBaudRates[1] = 19200; m_pBaudRates[2] = 38400; m_pBaudRates[3] = 57600; m_pBaudRates[4] = 115200;

            // Init Baudrates
            for (w_nI = (int)BAUD_RATE_Ndx.BAUD9600; w_nI <= (int)BAUD_RATE_Ndx.BAUD115200; w_nI ++)
            {
                ComboBoxItem w_cbiItem = new ComboBoxItem();
                w_cbiItem.Content = string.Format("{0}", m_pBaudRates[w_nI]);
                cmbCI_BaudRate.Items.Add(w_cbiItem);}
            cmbCI_BaudRate.SelectedIndex = (int)BAUD_RATE_Ndx.BAUD115200;
        }

        public void InitCommandControl()
        {
            byte w_nI;

            for (w_nI = 0; w_nI < m_pCmd.Count(); w_nI ++)
            {
                ComboBoxItem w_cbiItem = new ComboBoxItem();
                w_cbiItem.Content = m_pCmd.ElementAt(w_nI).m_strCmdName;
                cmbSC_Command.Items.Add(w_cbiItem);
            }

            for (w_nI = 0; w_nI < m_pStrParamMode.Count(); w_nI++)
            {
                ComboBoxItem w_cbiItem = new ComboBoxItem();
                w_cbiItem.Content = m_pStrParamMode.ElementAt(w_nI);
                cmbSC_ParamMode.Items.Add(w_cbiItem);
            }
            cmbSC_ParamMode.SelectedIndex = 0;

            for (w_nI = 0; w_nI < m_pStrParamIndex.Count(); w_nI++)
            {
                ComboBoxItem w_cbiItem = new ComboBoxItem();
                w_cbiItem.Content = m_pStrParamIndex.ElementAt(w_nI);
                cmbSC_ParamIndex.Items.Add(w_cbiItem);
            }
            cmbSC_ParamIndex.SelectedIndex = 0;
        }

        public void SetControlState(bool p_bIsConnected)
        {
            // Communication Information
            chkCI_Serial.IsEnabled = !p_bIsConnected;
            chkCI_USB.IsEnabled = !p_bIsConnected;
            if (p_bIsConnected == false)
            {
                cmbCI_COMPort.IsEnabled = !m_bConModeIsUSB;
                cmbCI_BaudRate.IsEnabled = !m_bConModeIsUSB;
            }
            else
            {
                cmbCI_COMPort.IsEnabled = !p_bIsConnected;
                cmbCI_BaudRate.IsEnabled = !p_bIsConnected;
            }
            btnCI_Connect.IsEnabled = !p_bIsConnected;
            btnCI_DisConnect.IsEnabled = p_bIsConnected;

            // Send Command
            cmbSC_Command.IsEnabled = p_bIsConnected;
            if (!p_bIsConnected)
                cmbSC_Command.SelectedIndex = -1;
            cmbSC_ParamMode.IsEnabled = p_bIsConnected;
            cmbSC_ParamIndex.IsEnabled = p_bIsConnected;
            edtSC_ParamValue.IsEnabled = p_bIsConnected;
            edtSC_Data.IsEnabled = p_bIsConnected;
            btnSC_SLED.IsEnabled = p_bIsConnected;
            btnSC_FpCancel.IsEnabled = p_bIsConnected;
            btnSC_Send.IsEnabled = p_bIsConnected;

            // Clear Information
            edtRC_Result.Clear();
        }

        private void ClearCmdInfo()
        {
            // Clear Command Information
            edtCP_Cmd.Clear();
            edtCP_Data.Clear();
            edtCP_CheckSum.Clear();
            edtCP_Packet.Clear();
        }

        private void ClearResponseInfo()
        {
            // Clear Response Information
            edtRP_Cmd.Clear();
            edtRP_Data.Clear();
            edtRP_CheckSum.Clear();
            edtRP_Return.Clear();
            edtRP_Packet.Clear();
            edtRC_Result.Clear();
        }

        private void EnableSendButton()
        {
            btnSC_Send.IsEnabled = true;
            btnSC_FpCancel.IsEnabled = false;
            cmbSC_Command.IsEnabled = true;
        }

        private bool CheckInputTemplateNo()
        {
            uint w_nLen = 0;
            int w_nIndex = 0;

            // Get Input Length
            w_nLen = (uint)edtSC_Data.Text.Length;

            // Check Length
            if ((w_nLen == 0) || (!int.TryParse(edtSC_Data.Text, out w_nIndex)))
            {
                MessageBox.Show("请输入正确的编号!", "输入错误", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return false;
            }
            if (w_nLen > 4)
            {
                MessageBox.Show("请输入正确的编号!", "输入错误", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return false;
            }
            w_nIndex = int.Parse(edtSC_Data.Text);
            if ((w_nIndex < 1) || (w_nIndex > CommonDefine.GD_MAX_RECORD_COUNT))
            {
                MessageBox.Show(String.Format("请输入正确的编号!(1~{0})", CommonDefine.GD_MAX_RECORD_COUNT), "输入错误", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return false;
            }

            // Return Success
            return true;
        }

        private bool GetDeviceInfo()
        {
            // Get Device Info

            // Return
            return true;
        }

        private void chkCI_Serial_Click(object sender, RoutedEventArgs e)
        {
            // Select COM
            cmbCI_COMPort.IsEnabled = true;
            cmbCI_BaudRate.IsEnabled = true;

            m_bConModeIsUSB = false;
        }

        private void chkCI_USB_Click(object sender, RoutedEventArgs e)
        {
            // Select USB
            cmbCI_COMPort.IsEnabled = false;
            cmbCI_BaudRate.IsEnabled = false;

            m_bConModeIsUSB = true;
        }

        private void btnCI_Connect_Click(object sender, RoutedEventArgs e)
        {
            bool w_bRet;

            if (m_bConModeIsUSB)
            {
                // USB
                if (!m_clsCmdProc.Run_Connect(true, "", 0))
                {
                    MessageBox.Show("目标没响应", "通讯错误", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    return;
                }
            }
            else
            {
                // COM
                string w_strCOMPort;
                uint w_nBaudrate;

                w_nBaudrate = m_pBaudRates[cmbCI_BaudRate.SelectedIndex];
                w_strCOMPort = cmbCI_COMPort.Text;

                if (!m_clsCmdProc.Run_Connect(false, w_strCOMPort, w_nBaudrate))
                {
                    MessageBox.Show("打开串口失败", "通讯错误", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    return;
                }
            }

            // Test Connection
            w_bRet = m_clsCmdProc.Run_TestConnection();
            if (!w_bRet)
            {
                btnCI_DisConnect_Click(sender, e);
                MessageBox.Show("目标没响应", "通讯错误", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return;
            }

            // Get Device Information
            if (!GetDeviceInfo())
            {
                btnCI_DisConnect_Click(sender, e);
                MessageBox.Show("目标没响应", "通讯错误", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return;
            }

            // Connected
            SetControlState(true);
            edtRC_Result.Text = "设备已连接";
            btnSC_FpCancel.IsEnabled = false;
            btnSC_Send.IsEnabled = false;
        }

        private void btnCI_DisConnect_Click(object sender, RoutedEventArgs e)
        {
            // Disconnect Device
            if (!m_clsCmdProc.Run_Disconnect())
            {
                MessageBox.Show("断开连接失败", "通讯错误", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return;
            }

            // Disconnect Success
            SetControlState(false);
        }

        private void cmbSC_Command_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // Clear Old Informations
            ClearCmdInfo();
            ClearResponseInfo();

            // Hide Controls
            lblSC_Data.Visibility = Visibility.Hidden;
            lblSC_Index.Visibility = Visibility.Hidden;
            lblSC_Mode.Visibility = Visibility.Hidden;
            lblSC_Value.Visibility = Visibility.Hidden;
            edtSC_Data.Visibility = Visibility.Hidden;
            edtSC_ParamValue.Visibility = Visibility.Hidden;
            cmbSC_ParamIndex.Visibility = Visibility.Hidden;
            cmbSC_ParamMode.Visibility = Visibility.Hidden;

            // Init Control
            btnSC_Send.IsEnabled = true;
            btnSC_FpCancel.IsEnabled = false;

            // Get Current Index
            m_nCmdIndex = cmbSC_Command.SelectedIndex;

            switch (m_nCmdIndex)
            {
                case (int)(COMMAND_NDX.CMD_VERIFY):
                case (int)(COMMAND_NDX.CMD_ENROLL):
                case (int)(COMMAND_NDX.CMD_ENROLL_ONETIME):
                case (int)(COMMAND_NDX.CMD_CHANGE_TEMPLATE):
                case (int)(COMMAND_NDX.CMD_CLEAR_TEMPLATE):
                case (int)(COMMAND_NDX.CMD_VERIFY_WITH_DOWN_IMAGE):
                case (int)(COMMAND_NDX.CMD_READ_TEMPLATE):
                case (int)(COMMAND_NDX.CMD_WRITE_TEMPLATE):
                case (int)(COMMAND_NDX.CMD_VERIFY_WITH_DOWN_TMPL):
                    lblSC_Data.Content = "指纹编号 :";
                    lblSC_Data.Visibility = Visibility.Visible;
                    edtSC_Data.Visibility = Visibility.Visible;
                    edtSC_Data.Text = "";
                    break;
                case (int)(COMMAND_NDX.CMD_SET_DEVPASS):
                case (int)(COMMAND_NDX.CMD_VERIFY_DEVPASS):
                    lblSC_Data.Content = "密码 :";
                    lblSC_Data.Visibility = Visibility.Visible;
                    edtSC_Data.Visibility = Visibility.Visible;
                    edtSC_Data.Text = "";
                    break;
                case (int)(COMMAND_NDX.CMD_SET_PARAMETER):
                    lblSC_Mode.Visibility = Visibility.Visible;
                    cmbSC_ParamMode.Visibility = Visibility.Visible;
                    lblSC_Index.Visibility = Visibility.Visible;
                    cmbSC_ParamIndex.Visibility = Visibility.Visible;
                    lblSC_Value.Visibility = Visibility.Visible;
                    edtSC_ParamValue.Visibility = Visibility.Visible;
                    edtSC_ParamValue.Text = "";
                    break;
                default:
                    break;
            }
        }

        private void btnSC_Send_Click(object sender, RoutedEventArgs e)
        {
            // Change Control Status
            btnSC_Send.IsEnabled = false;
            cmbSC_Command.IsEnabled = false;

            // Clear Old Informations
            ClearCmdInfo();
            ClearResponseInfo();

            // Save Sender & RoutedEventArgs
            m_objSender = sender;
            m_argEvent = e;

            // Run Command
            switch (m_nCmdIndex)
            {
                case (int)(COMMAND_NDX.CMD_ENROLL):
                    Run_Enroll();
                    break;
                case (int)(COMMAND_NDX.CMD_VERIFY):
                    Run_Verify();
                    break;
                case (int)(COMMAND_NDX.CMD_IDENTIFY):
                    Run_Identify();
                    break;
                case (int)(COMMAND_NDX.CMD_IDENTIFY_FREE):
                    Run_IdentifyFree();
                    break;
                case (int)(COMMAND_NDX.CMD_ENROLL_ONETIME):
                    Run_EnrollOneTime();
                    break;
                case (int)(COMMAND_NDX.CMD_CHANGE_TEMPLATE):
                    Run_ChangeTemplate();
                    break;
                case (int)(COMMAND_NDX.CMD_CLEAR_TEMPLATE):
                    Run_ClearTemplate();
                    break;
                case (int)(COMMAND_NDX.CMD_CLEAR_ALLTEMPLATE):
                    Run_ClearAllTemplate();
                    break;
                case (int)(COMMAND_NDX.CMD_GET_EMPTY_ID):
                    Run_GetEmptyID();
                    break;
                case (int)(COMMAND_NDX.CMD_GET_BROKEN_TEMPLATE):
                    Run_GetBrokenTemplate();
                    break;
                case (int)(COMMAND_NDX.CMD_READ_TEMPLATE):
                    Run_ReadTemplate();
                    break;
                case (int)(COMMAND_NDX.CMD_WRITE_TEMPLATE):
                    Run_WriteTemplate();
                    break;
                case (int)(COMMAND_NDX.CMD_SET_PARAMETER):
                    Run_SetParameter();
                    break;
                case (int)(COMMAND_NDX.CMD_GET_FW_VERSION):
                    Run_GetFwVersion();
                    break;
                case (int)(COMMAND_NDX.CMD_FINGER_DETECT):
                    Run_FingerDetect();
                    break;
                case (int)(COMMAND_NDX.CMD_FEATURE_OF_CAPTURED_FP):
                    Run_GetFeatureOfCapturedFP();
                    break;
                case (int)(COMMAND_NDX.CMD_IDENTIFY_WITH_TMPL):
                    Run_IdentifyWithTemplate2();
                    break;
                case (int)(COMMAND_NDX.CMD_SET_DEVPASS):
                    Run_SetDevPass();
                    break;
                case (int)(COMMAND_NDX.CMD_VERIFY_DEVPASS):
                    Run_VerifyDevPass();
                    break;
                case (int)(COMMAND_NDX.CMD_EXIT_DEVPASS):
                    Run_ExitDevPass();
                    break;
                case (int)(COMMAND_NDX.CMD_GET_ENROLL_COUNT):
                    Run_GetEnrollCount();
                    break;
                case (int)(COMMAND_NDX.CMD_UP_IMAGE):
                    Run_UpImage();
                    break;
                case (int)(COMMAND_NDX.CMD_IDENTIFY_WITH_DOWN_IMAGE):
                    Run_IdentifyWithImage();
                    break;
                case (int)(COMMAND_NDX.CMD_VERIFY_WITH_DOWN_IMAGE):
                    Run_VerifyWithImage();
                    break;
                case (int)(COMMAND_NDX.CMD_IDENTIFY_WITH_DOWN_TMPL):
                    Run_IdentifyWithDownTmpl();
                    break;
                case (int)(COMMAND_NDX.CMD_VERIFY_WITH_DOWN_TMPL):
                    Run_VerifyWithDownTmpl();
                    break;
                case (int)(COMMAND_NDX.CMD_ADJUST_SENSOR):
                    Run_AdjustSensor();
                    break;
                case (int)(COMMAND_NDX.CMD_FP_CANCEL):
                    Run_FpCancel();
                    break;
                case (int)(COMMAND_NDX.CMD_ENTER_ISPMODE):
                    //Run_EnterISPMode();
                    break;
                default:
                    break;
            }
        }

        private void Run_Enroll()
        {
            bool w_bRet = false;
            uint w_nTempInd = 0;

            // Check Input
            if (!CheckInputTemplateNo())
            {
                EnableSendButton();
                return;
            }

            // Get Template Index
            w_nTempInd = (uint)(Int32.Parse(edtSC_Data.Text));

            // Enable FPCancel
            btnSC_FpCancel.IsEnabled = true;

            // Run Command
            w_bRet = m_clsCmdProc.Run_Command_1P((ushort)(CommonDefine.CMD_ENROLL_CODE), (ushort)w_nTempInd);
        }

        private void Run_Verify()
        {
            bool w_bRet = false;
            uint w_nTemplateNo = 0;

            //. Check inputed template no
            if (!CheckInputTemplateNo())
            {
                EnableSendButton();
                return;
            }

            w_nTemplateNo = (uint)(Int32.Parse(edtSC_Data.Text));
            edtRC_Result.Text = "请按手指";
            btnSC_FpCancel.IsEnabled = true;
            w_bRet = m_clsCmdProc.Run_Command_1P((ushort)(CommonDefine.CMD_VERIFY_CODE), (ushort)w_nTemplateNo);
        }

        private void Run_Identify()
        {
            bool w_bRet = false;

            edtRC_Result.Text = "请按手指";
            btnSC_FpCancel.IsEnabled = true;
            w_bRet = m_clsCmdProc.Run_Command_NP(CommonDefine.CMD_IDENTIFY_CODE);
        }

        private void Run_IdentifyFree()
        {
            bool w_bRet = false;

            edtRC_Result.Text = "请按手指";
            btnSC_FpCancel.IsEnabled = true;
            w_bRet = m_clsCmdProc.Run_Command_NP(CommonDefine.CMD_IDENTIFY_FREE_CODE);
        }

        private void Run_EnrollOneTime()
        {
            bool w_bRet = false;
            uint w_nTemplateNo = 0;

            //. Check inputed template no
            if (!CheckInputTemplateNo())
            {
                EnableSendButton();
                return;
            }

            w_nTemplateNo = (uint)(Int32.Parse(edtSC_Data.Text));
            edtRC_Result.Text = "请按手指";
            btnSC_FpCancel.IsEnabled = true;
            w_bRet = m_clsCmdProc.Run_Command_1P(CommonDefine.CMD_ENROLL_ONETIME_CODE, (ushort)w_nTemplateNo);
        }

        private void Run_ChangeTemplate()
        {
            bool w_bRet = false;
            uint w_nTemplateNo = 0;

            //. Check inputed template no
            if (!CheckInputTemplateNo())
            {
                EnableSendButton();
                return;
            }

            w_nTemplateNo = (uint)(Int32.Parse(edtSC_Data.Text));
            btnSC_FpCancel.IsEnabled = true;
            w_bRet = m_clsCmdProc.Run_Command_1P(CommonDefine.CMD_CHANGE_TEMPLATE_CODE, (ushort)w_nTemplateNo);
        }

        private void Run_ClearTemplate()
        {
            bool w_bRet = false;
            uint w_nTemplateNo = 0;

            //. Check inputed template no
            if (!CheckInputTemplateNo())
            {
                EnableSendButton();
                return;
            }
            w_nTemplateNo = (uint)(Int32.Parse(edtSC_Data.Text));
            w_bRet = m_clsCmdProc.Run_Command_1P(CommonDefine.CMD_CLEAR_TEMPLATE_CODE, (ushort)w_nTemplateNo);
        }

        private void Run_ClearAllTemplate()
        {
            m_clsCmdProc.Run_Command_NP(CommonDefine.CMD_CLEAR_ALLTEMPLATE_CODE);
        }

        private void Run_GetEmptyID()
        {
            m_clsCmdProc.Run_Command_NP(CommonDefine.CMD_GET_EMPTY_ID_CODE);
        }

        private void Run_GetBrokenTemplate()
        {
            m_clsCmdProc.Run_Command_NP(CommonDefine.CMD_GET_BROKEN_TEMPLATE_CODE);
        }

        private void Run_ReadTemplate()
        {
            bool w_bRet = false;
            uint w_nTemplateNo = 0;

            //. Check inputed template no
            if (!CheckInputTemplateNo())
            {
                EnableSendButton();
                return;
            }

            w_nTemplateNo = (uint)(Int32.Parse(edtSC_Data.Text));
            Array.Clear(m_pTemplateData, 0, CommonDefine.GD_RECORD_SIZE);

            //. Assemble command packet
            m_clsCmdProc.InitPacket(CommonDefine.CMD_READ_TEMPLATE_CODE, true);
            CommandProc.SET_PACKET_LEN((ushort)2, false);
            CommandProc.SET_PACKET_CMDDATA((ushort)w_nTemplateNo, 0, false);
            m_clsCmdProc.AddCheckSum(true);
            
            //. Display command information
            DisplayCommandPacket();

            m_clsCmdProc.m_nCmdCode = CommonDefine.CMD_READ_TEMPLATE_CODE;
            w_bRet = m_clsCmdProc.SEND_COMMAND(CommonDefine.CMD_READ_TEMPLATE_CODE);
            if (w_bRet == false)
            {
                btnCI_DisConnect_Click(m_objSender, m_argEvent);
                return;
            }
            if (CommandProc.GET_PACKET_RETURN(false) != CommonDefine.ERR_SUCCESS)
            {
                DisplayResponsePacket(CommonDefine.CMD_READ_TEMPLATE_CODE);
                return;
            }

            //w_blRet = ReceiveDataPacket( CMD_READ_TEMPLATE_CODE, RESPONSE_DATA1 );
            w_bRet = m_clsCmdProc.RECEIVE_DATAPACKET(CommonDefine.CMD_READ_TEMPLATE_CODE, CommandProc.GET_PACKET_RCMDATA(0, false));

            if (w_bRet == false)
                btnCI_DisConnect_Click(m_objSender, m_argEvent);
            else
                DisplayResponsePacket(CommonDefine.CMD_READ_TEMPLATE_CODE);
        }

        private void Run_WriteTemplate()
        {
            bool w_bRet = false;
            uint w_nTemplateNo = 0;

            //. Check inputed template no and Read template file
            if (CheckInputTemplateNo() == false || ReadTemplateFile() == false)
            {
                EnableSendButton();
                return;
            }

            w_nTemplateNo = (uint)(Int32.Parse(edtSC_Data.Text));
            btnCI_DisConnect.IsEnabled = false;

            //. Assemble command packet
            m_clsCmdProc.InitPacket(CommonDefine.CMD_WRITE_TEMPLATE_CODE, true);
            CommandProc.SET_PACKET_LEN((ushort)2, false);
            CommandProc.SET_PACKET_CMDDATA((ushort)CommonDefine.GD_RECORD_SIZE, 0, false);
            m_clsCmdProc.AddCheckSum(true);

            //. Display command information
            DisplayCommandPacket();

            //. Send command packet to target
            w_bRet = m_clsCmdProc.SEND_COMMAND(CommonDefine.CMD_WRITE_TEMPLATE_CODE);
            if (w_bRet == false)
            {
                goto err;
            }
            if (CommandProc.GET_PACKET_RETURN(false) != CommonDefine.ERR_SUCCESS)
            {
                //. Display response packet
                DisplayResponsePacket(CommonDefine.CMD_WRITE_TEMPLATE_CODE);
                return;
            }

            //. Assemble data packet
            m_clsCmdProc.InitPacket(CommonDefine.CMD_WRITE_TEMPLATE_CODE, false);
            CommandProc.SET_PACKET_LEN((ushort)(CommonDefine.GD_RECORD_SIZE + 2), false);
            CommandProc.SET_PACKET_CMDDATA((ushort)w_nTemplateNo, 0, false);
            Array.Copy(m_pTemplateData, 0, CommandProc.m_pPacketBuffer, CommonDefine.ST_CMDDATA_INDEX + 2, CommonDefine.GD_RECORD_SIZE);
            m_clsCmdProc.AddCheckSum(false);

            //. Display command information
            DisplayCommandPacket();
            edtRP_Data.Text = String.Format("{0, 4:X4}", w_nTemplateNo);
            edtRP_CheckSum.Text = String.Format("{0, 4:X4}", (ushort)(CommandProc.m_pPacketBuffer[CommandProc.GET_DATAPACKET_LEN(false) + 1] << 8 + CommandProc.m_pPacketBuffer[CommandProc.GET_DATAPACKET_LEN(false)]));
            edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommandProc.GET_DATAPACKET_LEN(false) + 2);

            //. Send data packet to target
            w_bRet = m_clsCmdProc.SEND_DATAPACKET(CommonDefine.CMD_WRITE_TEMPLATE_CODE);
            if (w_bRet == false)
            {
                goto err;
            }

            //. Display response packet
            DisplayResponsePacket(CommonDefine.CMD_WRITE_TEMPLATE_CODE);
            return;

err:
            btnCI_DisConnect_Click(m_objSender, m_argEvent);
            return;
        }

        private void Run_SetParameter()
        {
            int w_nMode, w_nIndex, w_nValue;

            w_nMode = cmbSC_ParamMode.SelectedIndex;
            w_nIndex = cmbSC_ParamIndex.SelectedIndex;
            if (edtSC_ParamValue.Text != "")
                w_nValue = Int32.Parse(edtSC_ParamValue.Text);
            else
                w_nValue = 0;

            if (w_nMode == 0)
                m_bParamGet = true;
            else
                m_bParamGet = false;

            m_clsCmdProc.InitPacket(CommonDefine.CMD_SET_PARAMETER_CODE, true);
            CommandProc.SET_PACKET_LEN((ushort)6, false);
            CommandProc.m_pPacketBuffer[CommonDefine.ST_CMDDATA_INDEX + 0] = (byte)w_nMode;     // Get or Set
            CommandProc.m_pPacketBuffer[CommonDefine.ST_CMDDATA_INDEX + 1] = (byte)w_nIndex;    // Parameter Index

            CommandProc.m_pPacketBuffer[CommonDefine.ST_CMDDATA_INDEX + 2] = (byte)(w_nValue & 0xFF); // Parameter Value
            CommandProc.m_pPacketBuffer[CommonDefine.ST_CMDDATA_INDEX + 3] = (byte)((w_nValue >> 8) & 0xFF);
            CommandProc.m_pPacketBuffer[CommonDefine.ST_CMDDATA_INDEX + 4] = (byte)((w_nValue >> 16) & 0xFF);
            CommandProc.m_pPacketBuffer[CommonDefine.ST_CMDDATA_INDEX + 5] = (byte)((w_nValue >> 24) & 0xFF);
            m_clsCmdProc.AddCheckSum(true);

            btnCI_DisConnect.IsEnabled = false;
            DisplayCommandPacket();
            m_clsCmdProc.m_nCmdCode = CommonDefine.CMD_SET_PARAMETER_CODE;
            m_clsCmdProc.StartSendThread();
        }

        private void Run_GetFwVersion()
        {
            m_clsCmdProc.Run_Command_NP(CommonDefine.CMD_GET_FW_VERSION_CODE);
        }

        private void Run_FingerDetect()
        {
            edtRC_Result.Text = "请按手指";
            btnCI_DisConnect.IsEnabled = true;
            m_clsCmdProc.Run_Command_NP(CommonDefine.CMD_FINGER_DETECT_CODE);
        }

        private void Run_GetFeatureOfCapturedFP()
        {
            bool w_bRet = false;

            btnCI_DisConnect.IsEnabled = false;
            btnSC_FpCancel.IsEnabled = true;

            Array.Clear(m_pTemplateData, 0, CommonDefine.GD_RECORD_SIZE);

            //. Assemble command packet
            m_clsCmdProc.InitPacket(CommonDefine.CMD_FEATURE_OF_CAPTURED_FP_CODE, true);
            m_clsCmdProc.AddCheckSum(true);

            //. Display command information
            DisplayCommandPacket();

            edtRC_Result.Text = "请按手指";

            m_clsCmdProc.m_nCmdCode = CommonDefine.CMD_FEATURE_OF_CAPTURED_FP_CODE;
            w_bRet = m_clsCmdProc.SEND_COMMAND(CommonDefine.CMD_FEATURE_OF_CAPTURED_FP_CODE);
            if (w_bRet == false)
            {
                btnCI_DisConnect_Click(m_objSender, m_argEvent);
                return;
            }

            if (CommandProc.GET_PACKET_RETURN(false) != CommonDefine.ERR_SUCCESS)
            {
                DisplayResponsePacket(CommonDefine.CMD_FEATURE_OF_CAPTURED_FP_CODE);
                return;
            }

            m_clsCmdProc.StartSendThread();
            return;
        }

        private void Run_IdentifyWithTemplate2()
        {
            bool w_bRet = false;

            //. Read template file
            if (ReadTemplateFile() == false || ReadTemplateFile2() == false)
            {
                EnableSendButton();
                return;
            }

            btnCI_DisConnect.IsEnabled = false;

            //. Assemble command packet
            m_clsCmdProc.InitPacket(CommonDefine.CMD_IDENTIFY_TEMPLATE_WITH_FP_CODE, true);
            CommandProc.SET_PACKET_LEN((ushort)2, false);
            CommandProc.SET_PACKET_CMDDATA((ushort)CommonDefine.GD_RECORD_SIZE, 0, false);
            m_clsCmdProc.AddCheckSum(true);

            //. Display command information
            DisplayCommandPacket();

            m_clsCmdProc.m_nCmdCode = CommonDefine.CMD_IDENTIFY_TEMPLATE_WITH_FP_CODE;
            w_bRet = m_clsCmdProc.SEND_COMMAND(CommonDefine.CMD_IDENTIFY_TEMPLATE_WITH_FP_CODE);
            if (w_bRet == false)
            {
                goto err;
            }
            if (CommandProc.GET_PACKET_RETURN(false) != CommonDefine.ERR_SUCCESS)
            {
                DisplayResponsePacket(CommonDefine.CMD_IDENTIFY_TEMPLATE_WITH_FP_CODE);
                return;
            }

            edtRC_Result.Text = "请按手指";

            //. Assemble data packet
            m_clsCmdProc.InitPacket(CommonDefine.CMD_IDENTIFY_TEMPLATE_WITH_FP_CODE, false);
            CommandProc.SET_PACKET_LEN(CommonDefine.GD_RECORD_SIZE + 2, false);
            CommandProc.m_pPacketBuffer[CommonDefine.ST_CMDDATA_INDEX + 0] = 0;	// Template Index
            CommandProc.m_pPacketBuffer[CommonDefine.ST_CMDDATA_INDEX + 1] = 0;	// Mode (0 : Set Buffer, 1 : Identify)
            Array.Copy(m_pTemplateData, 0, CommandProc.m_pPacketBuffer, CommonDefine.ST_CMDDATA_INDEX + 2, CommonDefine.GD_RECORD_SIZE);
            m_clsCmdProc.AddCheckSum(false);

            //. Display Data information
            DisplayCommandPacket();
            edtRP_CheckSum.Text = String.Format("{0, 4:X4}", (ushort)(CommandProc.m_pPacketBuffer[CommandProc.GET_DATAPACKET_LEN(false) + 1] << 8 + CommandProc.m_pPacketBuffer[CommandProc.GET_DATAPACKET_LEN(false)]));
            edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommandProc.GET_DATAPACKET_LEN(false) + 2);

            //. Send data packet to target
            w_bRet = m_clsCmdProc.SEND_DATAPACKET(CommonDefine.CMD_IDENTIFY_TEMPLATE_WITH_FP_CODE);
            if (w_bRet == false)
            {
                goto err;
            }

            if (CommandProc.GET_PACKET_RETURN(false) != CommonDefine.ERR_SUCCESS)
            {
                DisplayResponsePacket(CommonDefine.CMD_IDENTIFY_TEMPLATE_WITH_FP_CODE);
                return;
            }

            //. Assemble data packet
            m_clsCmdProc.InitPacket(CommonDefine.CMD_IDENTIFY_TEMPLATE_WITH_FP_CODE, false);
            CommandProc.SET_PACKET_LEN(CommonDefine.GD_RECORD_SIZE + 2, false);
            CommandProc.m_pPacketBuffer[CommonDefine.ST_CMDDATA_INDEX + 0] = 1;	// Template Index
            CommandProc.m_pPacketBuffer[CommonDefine.ST_CMDDATA_INDEX + 1] = 1;	// Mode (0 : Set Buffer, 1 : Set Buffer and Identify)
            Array.Copy(m_pTemplateData2, 0, CommandProc.m_pPacketBuffer, CommonDefine.ST_CMDDATA_INDEX + 2, CommonDefine.GD_RECORD_SIZE);
            m_clsCmdProc.AddCheckSum(false);

            //. Display Data information
            DisplayCommandPacket();
            edtRP_CheckSum.Text = String.Format("{0, 4:X4}", (ushort)(CommandProc.m_pPacketBuffer[CommandProc.GET_DATAPACKET_LEN(false) + 1] << 8 + CommandProc.m_pPacketBuffer[CommandProc.GET_DATAPACKET_LEN(false)]));
            edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommandProc.GET_DATAPACKET_LEN(false) + 2);

            //. Send data packet to target
            m_clsCmdProc.StartSendThread();
            
            Thread.Sleep(500);
            btnSC_FpCancel.IsEnabled = true;
            return;

err:
            btnCI_DisConnect_Click(m_objSender, m_argEvent);
            return;
        }

        private void Run_SetDevPass()
        {
	        if (edtSC_Data.Text.Length != 0 && edtSC_Data.Text.Length != 14)
	        {
		        MessageBox.Show("密码错误 \n请重新输入(密码长度=14)!", "输入错误", MessageBoxButton.OK, MessageBoxImage.Warning);
		        EnableSendButton();
		        return;
	        };

	        m_clsCmdProc.InitPacket(CommonDefine.CMD_SET_DEVPASS_CODE, true);
            CommandProc.SET_PACKET_LEN((ushort)14, false);
            if (edtSC_Data.Text.Length == 0)
                Array.Clear(CommandProc.m_pPacketBuffer, CommonDefine.ST_CMDDATA_INDEX, 14);
            else
                System.Buffer.BlockCopy(edtSC_Data.Text.ToCharArray(), 0, CommandProc.m_pPacketBuffer, CommonDefine.ST_CMDDATA_INDEX, 14);
	        m_clsCmdProc.AddCheckSum( true );

            btnCI_DisConnect.IsEnabled = false;
	        DisplayCommandPacket();
	        m_clsCmdProc.m_nCmdCode = CommonDefine.CMD_SET_DEVPASS_CODE;
	        m_clsCmdProc.StartSendThread();
        }

        private void Run_VerifyDevPass()
        {
	        if (edtSC_Data.Text.Length != 14)
	        {
		        MessageBox.Show("密码错误 \n请重新输入(密码长度=14)!", "输入错误", MessageBoxButton.OK, MessageBoxImage.Warning);
		        EnableSendButton();
		        return;
	        }

	        m_clsCmdProc.InitPacket(CommonDefine.CMD_VERIFY_DEVPASS_CODE, true);
            CommandProc.SET_PACKET_LEN((ushort)14, false);
            System.Buffer.BlockCopy(edtSC_Data.Text.ToCharArray(), 0, CommandProc.m_pPacketBuffer, CommonDefine.ST_CMDDATA_INDEX, 14);
	        m_clsCmdProc.AddCheckSum(true);

            btnCI_DisConnect.IsEnabled = false;
	        DisplayCommandPacket();
	        m_clsCmdProc.m_nCmdCode = CommonDefine.CMD_VERIFY_DEVPASS_CODE;
	        m_clsCmdProc.StartSendThread();
        }

        private void Run_ExitDevPass()
        {
            m_clsCmdProc.Run_Command_NP(CommonDefine.CMD_EXIT_DEVPASS_CODE);
        }

        private void Run_GetEnrollCount()
        {
            m_clsCmdProc.Run_Command_NP(CommonDefine.CMD_GET_ENROLL_COUNT_CODE);
        }

        private void Run_UpImage()
        {
            btnCI_DisConnect.IsEnabled = false;

            m_clsCmdProc.StartUpImageThread();
        }

        private void Run_IdentifyWithImage()
        {
            int			i, r, n, w_nImgSize;
	        bool		w_blRet = false;

	        //. Read template file
	        if (!ReadImage(CommandProc.g_pImageBuf))
	        {
		        EnableSendButton();
		        return;
	        }

	        btnCI_DisConnect.IsEnabled = false;

	        //. Assemble command packet
	        m_clsCmdProc.InitPacket(CommonDefine.CMD_IDENTIFY_WITH_IMAGE_CODE, true);
            CommandProc.SET_PACKET_LEN((ushort)4, false);
            CommandProc.SET_PACKET_CMDDATA((ushort)CommandProc.g_nImageWidth, 0, false);
            CommandProc.SET_PACKET_CMDDATA((ushort)CommandProc.g_nImageHeight, 2, false);
	        m_clsCmdProc.AddCheckSum( true );
	
	        //. Display command information
	        DisplayCommandPacket();
	
            m_clsCmdProc.m_nCmdCode = CommonDefine.CMD_IDENTIFY_WITH_IMAGE_CODE;
	        w_blRet = m_clsCmdProc.SEND_COMMAND(CommonDefine.CMD_IDENTIFY_WITH_IMAGE_CODE);
	        if(w_blRet == false)
	        {
		        btnCI_DisConnect_Click(m_objSender, m_argEvent);
		        return;
	        }
	
            if (CommandProc.GET_PACKET_RETURN(false) != CommonDefine.ERR_SUCCESS)
	        {
		        DisplayResponsePacket(CommonDefine.CMD_IDENTIFY_WITH_IMAGE_CODE);
		        return;
	        }	
	
	        if (m_bConModeIsUSB == false)
	        {
		        w_nImgSize = CommandProc.g_nImageWidth * CommandProc.g_nImageHeight;
		        n = w_nImgSize / CommonDefine.IMAGE_SEND_UNIT;
		        r = w_nImgSize % CommonDefine.IMAGE_SEND_UNIT;
		
		        for (i = 0; i < n; i ++)
		        {
			        //. Assemble data packet	
			        m_clsCmdProc.InitPacket(CommonDefine.CMD_IDENTIFY_WITH_IMAGE_CODE, false);
                    CommandProc.SET_PACKET_LEN((ushort)(4 + CommonDefine.GD_RECORD_SIZE), false);
                    CommandProc.SET_PACKET_CMDDATA((ushort)i, 0, false);
                    CommandProc.SET_PACKET_CMDDATA((ushort)CommonDefine.IMAGE_SEND_UNIT, 2, false);
                    Array.Copy(CommandProc.g_pImageBuf, i * CommonDefine.IMAGE_SEND_UNIT, CommandProc.m_pPacketBuffer, CommonDefine.ST_CMDDATA_INDEX + 4, CommonDefine.IMAGE_SEND_UNIT);
			        m_clsCmdProc.AddCheckSum(false);
			
			        w_blRet = m_clsCmdProc.SendDataPacket(CommonDefine.CMD_IDENTIFY_WITH_IMAGE_CODE);
			
			        if (!w_blRet)
				        goto err;
			
                    edtRC_Result.Text = String.Format("{0}%...", (i + 1) * CommonDefine.IMAGE_SEND_UNIT * 100 / w_nImgSize);
			        CommandProc.DoEvents();
		        }
		
		        if (r > 0)
		        {
			        m_clsCmdProc.InitPacket(CommonDefine.CMD_IDENTIFY_WITH_IMAGE_CODE, false);
                    CommandProc.SET_PACKET_LEN((ushort)(4 + CommonDefine.GD_RECORD_SIZE), false);
                    CommandProc.SET_PACKET_CMDDATA((ushort)i, 0, false);
                    CommandProc.SET_PACKET_CMDDATA((ushort)r, 2, false);
                    Array.Copy(CommandProc.g_pImageBuf, i * CommonDefine.IMAGE_SEND_UNIT, CommandProc.m_pPacketBuffer, CommonDefine.ST_CMDDATA_INDEX + 4, CommonDefine.IMAGE_SEND_UNIT);
			        m_clsCmdProc.AddCheckSum(false);
			
			        w_blRet = m_clsCmdProc.SendDataPacket(CommonDefine.CMD_IDENTIFY_WITH_IMAGE_CODE);
			
			        if (!w_blRet)
				        goto err;
		        }		

		        edtRC_Result.Text = String.Format("{0}%...", 100);
		        CommandProc.DoEvents();
	        }
	        else
	        {
		        w_blRet = m_clsUSB.USB_DownImage(CommandProc.g_pImageBuf, CommandProc.g_nImageWidth * CommandProc.g_nImageHeight);

		        if (!w_blRet)
			        goto err;
	        }

	        // Identify
	        m_clsCmdProc.InitPacket(CommonDefine.CMD_IDENTIFY_WITH_IMAGE_CODE, false );
            CommandProc.SET_PACKET_LEN((ushort)4, false);
            CommandProc.SET_PACKET_CMDDATA((ushort)0, 0, false);
            CommandProc.SET_PACKET_CMDDATA((ushort)0, 2, false);
	        m_clsCmdProc.AddCheckSum(false);

	        //. Display Data information
	        DisplayCommandPacket();
            edtCP_CheckSum.Text = String.Format("0x{0,4:X4}", (CommandProc.GET_DATAPACKET_LEN(false)));
            edtCP_Cmd.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, (int)(CommandProc.GET_DATAPACKET_LEN(false) + 2));
		
	        m_clsCmdProc.StartSendThread();
	        Thread.Sleep(200);
            btnSC_FpCancel.IsEnabled = true;
	        return;

        err:
            btnCI_DisConnect.IsEnabled = true;
            MessageBox.Show("接收错误! \n 请检查连接和目标", "SZ_OEMHost_C#", MessageBoxButton.OK, MessageBoxImage.Exclamation);
            btnCI_DisConnect_Click(m_objSender, m_argEvent);
	        EnableSendButton();
        }

        private void Run_VerifyWithImage()
        {
            int			i, r, n, w_nImgSize, w_nTemplateNo;
	        bool		w_blRet = false;

	        //. Check inputed template no
	        if (CheckInputTemplateNo() == false)
	        {
		        EnableSendButton();
		        return;
	        }

	        //. Read template file
	        if (!ReadImage(CommandProc.g_pImageBuf))
	        {
		        EnableSendButton();
		        return;
	        }
	
            w_nTemplateNo = Int32.Parse(edtSC_Data.Text);
            btnCI_DisConnect.IsEnabled = false;

	        //. Assemble command packet
	        m_clsCmdProc.InitPacket(CommonDefine.CMD_VERIFY_WITH_IMAGE_CODE, true);
            CommandProc.SET_PACKET_LEN((ushort)6, false);
            CommandProc.SET_PACKET_CMDDATA((ushort)w_nTemplateNo, 0, false);
            CommandProc.SET_PACKET_CMDDATA((ushort)CommandProc.g_nImageWidth, 2, false);
            CommandProc.SET_PACKET_CMDDATA((ushort)CommandProc.g_nImageHeight, 4, false);
	        m_clsCmdProc.AddCheckSum( true );
	
	        //. Display command information
	        DisplayCommandPacket();
	
            m_clsCmdProc.m_nCmdCode = CommonDefine.CMD_VERIFY_WITH_IMAGE_CODE;
	        w_blRet = m_clsCmdProc.SEND_COMMAND(CommonDefine.CMD_VERIFY_WITH_IMAGE_CODE);
	        if(w_blRet == false)
	        {
                btnCI_DisConnect_Click(m_objSender, m_argEvent);
		        return;
	        }
	
            if (CommandProc.GET_PACKET_RETURN(false) != CommonDefine.ERR_SUCCESS)
	        {
		        DisplayResponsePacket(CommonDefine.CMD_VERIFY_WITH_IMAGE_CODE);
		        return;
	        }

	        if (m_bConModeIsUSB == false)
	        {
		        w_nImgSize = CommandProc.g_nImageWidth * CommandProc.g_nImageHeight;
		        n = w_nImgSize / CommonDefine.IMAGE_SEND_UNIT;
		        r = w_nImgSize % CommonDefine.IMAGE_SEND_UNIT;

		        for (i = 0; i < n; i ++)
		        {
			        //. Assemble data packet
			        m_clsCmdProc.InitPacket(CommonDefine.CMD_VERIFY_WITH_IMAGE_CODE, false);
                    CommandProc.SET_PACKET_LEN((ushort)(4 + CommonDefine.GD_RECORD_SIZE), false);
                    CommandProc.SET_PACKET_CMDDATA((ushort)i, 0, false);
                    CommandProc.SET_PACKET_CMDDATA((ushort)CommonDefine.IMAGE_SEND_UNIT, 2, false);
                    Array.Copy(CommandProc.g_pImageBuf, i * CommonDefine.IMAGE_SEND_UNIT, CommandProc.m_pPacketBuffer, CommonDefine.ST_CMDDATA_INDEX + 4, CommonDefine.IMAGE_SEND_UNIT);
			        m_clsCmdProc.AddCheckSum(false);

			        w_blRet = m_clsCmdProc.SendDataPacket(CommonDefine.CMD_VERIFY_WITH_IMAGE_CODE);

			        if (!w_blRet)
				        goto err;

			        edtRC_Result.Text = String.Format("下载中 : {0}%...", (i + 1) * CommonDefine.IMAGE_SEND_UNIT * 100 / w_nImgSize);
			        CommandProc.DoEvents();
		        }
		
		        if (r > 0)
		        {
			        m_clsCmdProc.InitPacket(CommonDefine.CMD_VERIFY_WITH_IMAGE_CODE, false);
                    CommandProc.SET_PACKET_LEN((ushort)(4 + CommonDefine.GD_RECORD_SIZE), false);
                    CommandProc.SET_PACKET_CMDDATA((ushort)i, 0, false);
                    CommandProc.SET_PACKET_CMDDATA((ushort)r, 2, false);
                    Array.Copy(CommandProc.g_pImageBuf, i * CommonDefine.IMAGE_SEND_UNIT, CommandProc.m_pPacketBuffer, CommonDefine.ST_CMDDATA_INDEX + 4, CommonDefine.IMAGE_SEND_UNIT);
			        m_clsCmdProc.AddCheckSum(false);
			
			        w_blRet = m_clsCmdProc.SendDataPacket(CommonDefine.CMD_VERIFY_WITH_IMAGE_CODE);
			
			        if (!w_blRet)
				        goto err;
		        }

		        edtRC_Result.Text = String.Format("下载中 : {0}%...", 100);
		        CommandProc.DoEvents();
	        }
	        else
	        {
		        w_blRet = m_clsUSB.USB_DownImage(CommandProc.g_pImageBuf, CommandProc.g_nImageWidth * CommandProc.g_nImageHeight);
		
		        if (!w_blRet)
			        goto err;
	        }

	        // Identify
	        m_clsCmdProc.InitPacket(CommonDefine.CMD_VERIFY_WITH_IMAGE_CODE, false);
            CommandProc.SET_PACKET_LEN((ushort)4, false);
            CommandProc.SET_PACKET_CMDDATA((ushort)0, 0, false);
            CommandProc.SET_PACKET_CMDDATA((ushort)0, 2, false);
	        m_clsCmdProc.AddCheckSum(false);

	        //. Display Data information
	        DisplayCommandPacket();
            edtCP_CheckSum.Text = String.Format("0x{0,4:X4}", (CommandProc.GET_DATAPACKET_LEN(false)));
            edtCP_Cmd.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, (int)(CommandProc.GET_DATAPACKET_LEN(false) + 2));
	
	        m_clsCmdProc.StartSendThread();
	        Thread.Sleep(200);
            btnSC_FpCancel.IsEnabled = true;
	        return;

        err:
            btnCI_DisConnect.IsEnabled = true;
            MessageBox.Show("接收错误! \n 请检查连接和目标", "SZ_OEMHost_C#", MessageBoxButton.OK, MessageBoxImage.Exclamation);
            btnCI_DisConnect_Click(m_objSender, m_argEvent);
	        EnableSendButton();
	        return;
        }

        private void Run_IdentifyWithDownTmpl()
        {
            bool w_bRet = false;

            btnCI_DisConnect.IsEnabled = false;

            //. Read template file
            w_bRet = ReadTemplateFile();
            if (w_bRet == false)
            {
                goto err;
            }
            //. Assemble command packet
            m_clsCmdProc.InitPacket(CommonDefine.CMD_IDENTIFY_WITH_DOWN_TMPL_CODE, true);
            CommandProc.SET_PACKET_LEN((ushort)2, false);
            CommandProc.SET_PACKET_CMDDATA((ushort)CommonDefine.GD_RECORD_SIZE, 0, false);
            m_clsCmdProc.AddCheckSum(true);

            //. Display command information
            DisplayCommandPacket();

            m_clsCmdProc.m_nCmdCode = CommonDefine.CMD_IDENTIFY_WITH_DOWN_TMPL_CODE;
            w_bRet = m_clsCmdProc.SEND_COMMAND(CommonDefine.CMD_IDENTIFY_WITH_DOWN_TMPL_CODE);
            if (w_bRet == false)
            {
                btnCI_DisConnect_Click(m_objSender, m_argEvent);
                return;
            }
            if (CommandProc.GET_PACKET_RETURN(false) != CommonDefine.ERR_SUCCESS)
            {
                DisplayResponsePacket(CommonDefine.CMD_IDENTIFY_WITH_DOWN_TMPL_CODE);
                return;
            }

            //. Assemble data packet
            m_clsCmdProc.InitPacket(CommonDefine.CMD_IDENTIFY_WITH_DOWN_TMPL_CODE, false);
            CommandProc.SET_PACKET_LEN(CommonDefine.GD_RECORD_SIZE, false);
            Array.Copy(m_pTemplateData, 0, CommandProc.m_pPacketBuffer, CommonDefine.ST_CMDDATA_INDEX, CommonDefine.GD_RECORD_SIZE);
            m_clsCmdProc.AddCheckSum(false);

            //. Display Data information
            DisplayCommandPacket();
            edtRP_CheckSum.Text = String.Format("{0, 4:X4}", (ushort)(CommandProc.m_pPacketBuffer[CommandProc.GET_DATAPACKET_LEN(false) + 1] << 8 + CommandProc.m_pPacketBuffer[CommandProc.GET_DATAPACKET_LEN(false)]));
            edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommandProc.GET_DATAPACKET_LEN(false) + 2);

            m_clsCmdProc.StartSendThread();
            Thread.Sleep(200);
            btnSC_FpCancel.IsEnabled = true;
            return;

err:
            EnableSendButton();
            return;
        }

        private void Run_VerifyWithDownTmpl()
        {
            int w_nTemplateNo;
            bool w_bRet = false;

            btnCI_DisConnect.IsEnabled = false;

            //. Check inputed template no
            if (CheckInputTemplateNo() == false)
            {
                goto err;
            }

            w_nTemplateNo = Int32.Parse(edtSC_Data.Text);

            //. Read template file
            w_bRet = ReadTemplateFile();
            if (w_bRet == false)
            {
                goto err;
            }
            //. Assemble command packet
            m_clsCmdProc.InitPacket(CommonDefine.CMD_VERIFY_WITH_DOWN_TMPL_CODE, true);
            CommandProc.SET_PACKET_LEN((ushort)4, false);
            CommandProc.SET_PACKET_CMDDATA((ushort)w_nTemplateNo, 0, false);
            CommandProc.SET_PACKET_CMDDATA((ushort)CommonDefine.GD_RECORD_SIZE, 2, false);
            m_clsCmdProc.AddCheckSum(true);

            //. Display command information
            DisplayCommandPacket();

            m_clsCmdProc.m_nCmdCode = CommonDefine.CMD_VERIFY_WITH_DOWN_TMPL_CODE;
            w_bRet = m_clsCmdProc.SEND_COMMAND(CommonDefine.CMD_VERIFY_WITH_DOWN_TMPL_CODE);
            if (w_bRet == false)
            {
                btnCI_DisConnect_Click(m_objSender, m_argEvent);
                return;
            }
            if (CommandProc.GET_PACKET_RETURN(false) != CommonDefine.ERR_SUCCESS)
            {
                DisplayResponsePacket(CommonDefine.CMD_VERIFY_WITH_DOWN_TMPL_CODE);
                return;
            }

            //. Assemble data packet
            m_clsCmdProc.InitPacket(CommonDefine.CMD_VERIFY_WITH_DOWN_TMPL_CODE, false);
            CommandProc.SET_PACKET_LEN(CommonDefine.GD_RECORD_SIZE, false);
            Array.Copy(m_pTemplateData, 0, CommandProc.m_pPacketBuffer, CommonDefine.ST_CMDDATA_INDEX, CommonDefine.GD_RECORD_SIZE);
            m_clsCmdProc.AddCheckSum(false);

            //. Display Data information
            DisplayCommandPacket();
            edtRP_CheckSum.Text = String.Format("{0, 4:X4}", (ushort)(CommandProc.m_pPacketBuffer[CommandProc.GET_DATAPACKET_LEN(false) + 1] << 8 + CommandProc.m_pPacketBuffer[CommandProc.GET_DATAPACKET_LEN(false)]));
            edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommandProc.GET_DATAPACKET_LEN(false) + 2);
            
            m_clsCmdProc.StartSendThread();
            Thread.Sleep(200);
            btnSC_FpCancel.IsEnabled = true;
            return;

err:
            EnableSendButton();
            return;
        }

        private void Run_AdjustSensor()
        {
            edtRC_Result.Text = "Adjusting sensor...";
            m_clsCmdProc.Run_Command_NP(CommonDefine.CMD_ADJUST_SENSOR_CODE);
        }

        private void Run_FpCancel()
        {
            btnCI_DisConnect.IsEnabled = false;
            m_clsCmdProc.StartFpCancelThread();
        }

        private void Run_EnterISPMode()
        {
            m_clsCmdProc.Run_Command_NP(CommonDefine.CMD_ENTER_ISPMODE_CODE);
        }

        public void DisplayCommandPacket()
        {
            // Clear Command Information
            ClearCmdInfo();
            edtCP_Cmd.Text = String.Format("0x{0,4:X4}", CommandProc.GET_PACKET_COMMAND(false));
            edtCP_CheckSum.Text = String.Format("0x{0,4:X4}", (CommandProc.m_pPacketBuffer[CommonDefine.ST_COM_PACKET_LEN + 1] << 8) + CommandProc.m_pPacketBuffer[CommonDefine.ST_COM_PACKET_LEN]);
            if (CommandProc.GET_PACKET_LEN(false) > 8)
                edtCP_Data.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_CMDDATA_INDEX, 8);
            else
                edtCP_Data.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_CMDDATA_INDEX, CommandProc.GET_PACKET_LEN(false));
            edtCP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
        }

        public String ConvertByteToHex(byte[] p_pBuff, int p_nSize)
        {
            return ConvertByteToHex(p_pBuff, 0, p_nSize);
        }

        public String ConvertByteToHex(byte[] p_pBuff, int p_nIndex, int p_nSize)
        {
            String w_szTemp, w_szData = "";
            int w_nI;

            // Convert Data
            for (w_nI = 0; w_nI < p_nSize; w_nI++)
            {
                if (((w_nI % 16) == 0) && (w_nI > 0))
                {
                    w_szData += "\n";
                }
                else if (((w_nI % 8) == 0) && (w_nI > 0))
                {
                    w_szData += "  ";
                }
                w_szTemp = String.Format("{0, 2:X2} ", p_pBuff[p_nIndex + w_nI]);
                w_szData += w_szTemp;
            }

            // Return
            return w_szData;
        }

        public void ProcessMessage(uint p_nMessage, int p_nWParam, int p_nLParam)
        {
            switch (p_nMessage)
            {
                case CommonDefine.WM_RECEIVE:
                    if (p_nWParam == 1)
                        ProcessRspPacket(true);
                    else
                        ProcessRspPacket(false);
                    break;
                case CommonDefine.WM_DISPLAY_PACKET:
                    DisplayCommandPacket();
                    break;
                case CommonDefine.WM_USER_UPDATE_0:
                    break;
                default:
                    break;
            }
        }

        public void ProcessRspPacket(bool p_bRet)
        {
	        if (p_bRet == false)
	        {
                btnCI_DisConnect.IsEnabled = true;
                MessageBox.Show("接收错误! \n 请检查连接和目标", CommonDefine.MSG_TITLE, MessageBoxButton.OK, MessageBoxImage.Warning);
                btnCI_DisConnect_Click(m_objSender, m_argEvent);
		        return;
	        }

	        //. Display response packet
	        DisplayResponsePacket(CommandProc.GET_PACKET_COMMAND(false));
	        return;
        }

        public void DisplayResponsePacket(ushort p_nCode)
        {
	        int	    w_nRet;
	        ushort	w_nData = 0;
            ushort  w_nData2 = 0;
            ushort  w_nRcvCks = 0;
            ushort  w_nSize = 0;

            ClearResponseInfo();

	        if (CommandProc.GET_PACKET_PREFIX(false) == CommonDefine.RCM_PREFIX_CODE)
                w_nRcvCks = (ushort)((CommandProc.m_pPacketBuffer[CommonDefine.ST_COM_PACKET_LEN + 1] << 8) + CommandProc.m_pPacketBuffer[CommonDefine.ST_COM_PACKET_LEN]);
	        else if (CommandProc.GET_PACKET_PREFIX(false) == CommonDefine.RCM_DATA_PREFIX_CODE)
                w_nRcvCks = (ushort)((CommandProc.m_pPacketBuffer[CommandProc.GET_DATAPACKET_LEN(false) + 1] << 8) + CommandProc.m_pPacketBuffer[CommandProc.GET_DATAPACKET_LEN(false)]);

            w_nRet = (int)CommandProc.GET_PACKET_RETURN(false);
            w_nData = CommandProc.GET_PACKET_RCMDATA(0, false); // MAKEWORD(g_Packet[8], g_Packet[9]);
            w_nData2 = CommandProc.GET_PACKET_RCMDATA(2, false); //MAKEWORD(g_Packet[10], g_Packet[11]);
            w_nSize = CommandProc.GET_PACKET_LEN(false);

            edtRP_Cmd.Text = String.Format("{0, 4:X4}", p_nCode);
            edtRP_Return.Text = String.Format("{0, 4:X4}", w_nRet);
            edtRP_Data.Text = String.Format("{0, 4:X4}", w_nData);
            edtRP_CheckSum.Text = String.Format("{0, 4:X4}", w_nRcvCks);

	        switch (p_nCode)
	        {
 		        case CommonDefine.CMD_CLEAR_TEMPLATE_CODE:
                    btnCI_DisConnect.IsEnabled = true;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
                        edtRC_Result.Text = String.Format("结果 : 成功\r\n指纹编号 : {0}", w_nData);
			        else
                        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
                    edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
			        break;

		        case CommonDefine.CMD_UP_IMAGE_CODE:
                    btnCI_DisConnect.IsEnabled = true;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
			        {
                        edtRC_Result.Text = String.Format("结果 : 图像接收成功");
                        Microsoft.Win32.SaveFileDialog w_cfdSaveImage = new Microsoft.Win32.SaveFileDialog();
                        w_cfdSaveImage.DefaultExt = ".bmp";
                        w_cfdSaveImage.Filter = "Image File(*.bmp)|*.bmp";

                        if (w_cfdSaveImage.ShowDialog() == true)
                        {
                            WriteBMP(w_cfdSaveImage.FileName, CommandProc.g_pImageBuf, CommandProc.g_nImageWidth, CommandProc.g_nImageHeight);
                            MessageBox.Show("保存成功");
                        }
			        }
			        else
			        {
                        edtRC_Result.Text = String.Format("结果 : Faile\r\n{0}", GetErrorMsg(w_nData));
			        }
			        break;

		        case CommonDefine.CMD_READ_TEMPLATE_CODE:
                    btnCI_DisConnect.IsEnabled = true;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
			        {
				        if (w_nSize != CommonDefine.GD_RECORD_SIZE + 4)
				        {
                            edtRC_Result.Text = String.Format("结果 : 错误\r\n通讯错误");
				        }
				        else
				        {
                            Array.Copy(CommandProc.m_pPacketBuffer, 10, m_pTemplateData, 0, CommonDefine.GD_RECORD_SIZE);
                            edtRC_Result.Text = String.Format("结果 : 成功\r\n指纹编号 : {0}", w_nData);
					        WriteTemplateFile(m_pTemplateData);
                            edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, w_nSize + 8);
				        }
			        }
			        else
			        {
                        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
                        edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
			        }
			        break;

		        case CommonDefine.CMD_WRITE_TEMPLATE_CODE:
                    btnCI_DisConnect.IsEnabled = true;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
                    {
                        edtRC_Result.Text = String.Format("结果 : 成功\r\n指纹编号 : {0}", w_nData);
			        }
			        else
                    {
                        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));

				        if (w_nData == CommonDefine.ERR_DUPLICATION_ID)
                            edtRC_Result.Text += String.Format(" {0}.", w_nData2);
			        }
                    if (CommandProc.GET_PACKET_PREFIX(false) == CommonDefine.RCM_PREFIX_CODE)
                        edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
                    else if (CommandProc.GET_PACKET_PREFIX(false) == CommonDefine.RCM_DATA_PREFIX_CODE)
                        edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommandProc.GET_DATAPACKET_LEN(false) + 2);
			        break;

		        case CommonDefine.CMD_GET_EMPTY_ID_CODE:
                    btnCI_DisConnect.IsEnabled = true;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
                        edtRC_Result.Text = String.Format("结果 : 成功\r\n可以编号 : {0}", w_nData);
			        else
                        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
                    edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
			        break;

		        case CommonDefine.CMD_GET_ENROLL_COUNT_CODE:
                    btnCI_DisConnect.IsEnabled = true;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
                        edtRC_Result.Text = String.Format("结果 : 成功\r\n指纹数量 : {0}", w_nData);
			        else
                        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
                    edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
			        break;

		        case CommonDefine.CMD_VERIFY_WITH_DOWN_TMPL_CODE:
		        case CommonDefine.CMD_IDENTIFY_WITH_DOWN_TMPL_CODE:
		        case CommonDefine.CMD_VERIFY_CODE :
		        case CommonDefine.CMD_IDENTIFY_CODE:
		        case CommonDefine.CMD_IDENTIFY_FREE_CODE:
		        case CommonDefine.CMD_ENROLL_CODE:
		        case CommonDefine.CMD_ENROLL_ONETIME_CODE:
		        case CommonDefine.CMD_CHANGE_TEMPLATE_CODE:
		        case CommonDefine.CMD_IDENTIFY_WITH_IMAGE_CODE:
		        case CommonDefine.CMD_VERIFY_WITH_IMAGE_CODE:
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
                    {
				        switch(w_nData)
				        {
				        case CommonDefine.GD_NEED_RELEASE_FINGER:
					        edtRC_Result.Text = "请离开手指";
					        break;
                        case CommonDefine.GD_NEED_FIRST_SWEEP:
                            edtRC_Result.Text = "请按手指";
					        break;
                        case CommonDefine.GD_NEED_SECOND_SWEEP:
                            edtRC_Result.Text = "请再按一次";
					        break;
                        case CommonDefine.GD_NEED_THIRD_SWEEP:
                            edtRC_Result.Text = "请再按一次";
					        break;
				        default:
                            if (p_nCode != CommonDefine.CMD_IDENTIFY_FREE_CODE || CommandProc.LOBYTE(w_nData) == CommonDefine.ERR_FP_CANCEL)
                                btnCI_DisConnect.IsEnabled = true;
                            edtRC_Result.Text = String.Format("结果 : 成功\r\n指纹编号 : {0}", w_nData);
                            break;
				        }
			        }
			        else{
				        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
				        if (CommandProc.LOBYTE(w_nData) == CommonDefine.ERR_BAD_QUALITY)
				        {
                            edtRC_Result.Text += "\r\nAgain... !";
				        }
				        else
				        {
					        if (w_nData == CommonDefine.ERR_DUPLICATION_ID)
					        {
                                edtRC_Result.Text += String.Format(" {0}.", w_nData2);
					        }
				        }
                        if (p_nCode != CommonDefine.CMD_IDENTIFY_FREE_CODE || CommandProc.LOBYTE(w_nData) == CommonDefine.ERR_FP_CANCEL ||
                            CommandProc.LOBYTE(w_nData) == CommonDefine.ERR_ALL_TMPL_EMPTY || CommandProc.LOBYTE(w_nData) == CommonDefine.ERR_INVALID_OPERATION_MODE ||
                            CommandProc.LOBYTE(w_nData) == CommonDefine.ERR_NOT_AUTHORIZED)
                            btnCI_DisConnect.IsEnabled = true;
			        }
                    edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
			        break;

		        case CommonDefine.CMD_CLEAR_ALLTEMPLATE_CODE :
                    btnCI_DisConnect.IsEnabled = true;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
                        edtRC_Result.Text = String.Format("结果 : 成功\r\nCleared Template Count : {0}", w_nData);
			        else
                        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
                    edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
			        break;

		        case CommonDefine.CMD_GET_BROKEN_TEMPLATE_CODE :
                    btnCI_DisConnect.IsEnabled = true;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
                        edtRC_Result.Text = String.Format("结果 : 成功\r\n损坏的指纹数量 : {0}\r\n第一个损坏的指纹编号 : {1}", w_nData, w_nData2);
			        else
                        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
                    edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
			        break;

		        case CommonDefine.CMD_VERIFY_DEVPASS_CODE:
		        case CommonDefine.CMD_SET_DEVPASS_CODE:
		        case CommonDefine.CMD_EXIT_DEVPASS_CODE:
        //		case CommonDefine.CMD_SET_COMMNAD_VALID_FLAG_CODE:
                    btnCI_DisConnect.IsEnabled = true;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
                        edtRC_Result.Text = String.Format("结果 : 成功");
			        else
				        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
                    edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
			        break;

		        case CommonDefine.CMD_SET_PARAMETER_CODE:
                    btnCI_DisConnect.IsEnabled = true;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
                    {
				        if (m_bParamGet)
                            edtRC_Result.Text = String.Format("结果 : 成功\r\n参数值 = {0}", CommandProc.GET_PACKET_RCMDATA(0, false));
				        else
                            edtRC_Result.Text = String.Format("结果 : 成功");
			        }
			        else
                    {
                        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
			        }
                    edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
			        break;

        // 		case CommonDefine.CMD_GET_COMMNAD_VALID_FLAG_CODE:
        // 			m_CtrlBnClosePort.EnableWindow(TRUE);
        // 			if(w_nRet == ERR_SUCCESS ){
        // 				MessageBeep(MB_ICONEXCLAMATION);
        // 				m_strResultMsg.Format("Result : Success\r\nCommand Valid Flag = %u", *(DWORD*)g_pPacketBuffer->stRcmData.tbRcmData);
        // 			}
        // 			else{
        // 				MessageBeep(MB_OK);
        // 				m_strResultMsg.Format( "Result : 错误\r\n");
        // 				m_strResultMsg += GetErrorMsg(w_nData);
        // 			}
        // 			m_strRcmPkt = ConvertByteToHex(g_Packet, CMD_PACKET_LEN+2);
        // 			break;

		        case CommonDefine.CMD_ADJUST_SENSOR_CODE:
                    btnCI_DisConnect.IsEnabled = true;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
                        edtRC_Result.Text = String.Format("结果 : 校准成功");
			        else
                        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
                    edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
			        break;

		        case CommonDefine.CMD_GET_FW_VERSION_CODE :
                    btnCI_DisConnect.IsEnabled = true;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
                        edtRC_Result.Text = String.Format("结果 : 成功\r\n固件版本 : {0}.{1}", CommandProc.LOBYTE(w_nData), CommandProc.HIBYTE(w_nData));
			        else
                        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
                    edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
			        break;

		        case CommonDefine.CMD_FINGER_DETECT_CODE :
                    btnCI_DisConnect.IsEnabled = true;
                    if (w_nRet == CommonDefine.ERR_SUCCESS)
                    {
                        if (w_nData == CommonDefine.GD_DETECT_FINGER)
                            edtRC_Result.Text = String.Format("检测到指纹");
                        else if (w_nData == CommonDefine.GD_NO_DETECT_FINGER)
                            edtRC_Result.Text = String.Format("没有检测到指纹");
                        else
                            edtRC_Result.Text = String.Format("通讯错误.");
                    }
                    else
                    {
                        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
                    }
                    edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
			        break;

		        case CommonDefine.CMD_FP_CANCEL_CODE :
                    btnCI_DisConnect.IsEnabled = true;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
                        edtRC_Result.Text = String.Format("结果 : 取消命令成功");
			        else
                        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
                    edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
			        break;

 		        case CommonDefine.CMD_FEATURE_OF_CAPTURED_FP_CODE:
                    btnCI_DisConnect.IsEnabled = true;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
			        {
				        if (w_nSize != CommonDefine.GD_RECORD_SIZE + 2)
				        {
                            edtRC_Result.Text = String.Format("结果 : 错误\r\n通讯错误");
				        }
				        else
				        {
                            Array.Copy(CommandProc.m_pPacketBuffer, 8, m_pTemplateData, 0, CommonDefine.GD_RECORD_SIZE);
                            edtRC_Result.Text = String.Format("结果 : 成功");
				        }
                        edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, w_nSize + 2);
			        }
			        else
			        {
                        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
                        if (CommandProc.GET_PACKET_PREFIX(false) == CommonDefine.CMD_PREFIX_CODE)
                            edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
				        else
                            edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommandProc.GET_DATAPACKET_LEN(false) + 2);
			        }
			        break;

		        case CommonDefine.CMD_IDENTIFY_TEMPLATE_WITH_FP_CODE:
                    if (CommandProc.GET_PACKET_PREFIX(false) == CommonDefine.CMD_PREFIX_CODE)
                        edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
                    else
                        edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommandProc.GET_DATAPACKET_LEN(false) + 2);
                    btnSC_FpCancel.IsEnabled = false;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
			        {
                        if (CommandProc.LOBYTE(w_nData) == CommonDefine.GD_DOWNLOAD_SUCCESS)
				        {
                            edtRC_Result.Text = String.Format("结果 : 写入成功\r\n请按手指");
					        return;
				        }
				        else
				        {
                            btnCI_DisConnect.IsEnabled = true;
                            edtRC_Result.Text = String.Format("结果 : 比对成功");
				        }
			        }
			        else
			        {
                        btnCI_DisConnect.IsEnabled = true;
                        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
			        }
			        break;
		
		        case CommonDefine.RCM_INCORRECT_COMMAND_CODE :
                    edtRC_Result.Text = String.Format("接收到错误的指令 !");
                    edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
			        break;

		        case CommonDefine.CMD_ENTER_ISPMODE_CODE:
                    btnCI_DisConnect.IsEnabled = true;
			        if (w_nRet == CommonDefine.ERR_SUCCESS)
                        edtRC_Result.Text = String.Format("结果 : 成功\r\nRunning ISP. Can you programming.");
			        else
                        edtRC_Result.Text = String.Format("结果 : 错误\r\n{0}", GetErrorMsg(w_nData));
                    edtRP_Packet.Text = ConvertByteToHex(CommandProc.m_pPacketBuffer, CommonDefine.ST_COM_PACKET_LEN + 2);
			        break;
		        default:
			        break;
	        }

	        if ((p_nCode == CommonDefine.CMD_IDENTIFY_FREE_CODE))
	        {
		        if (w_nRet == CommonDefine.ERR_SUCCESS ||
                     CommandProc.LOBYTE(w_nData) != CommonDefine.ERR_NOT_AUTHORIZED &&
                     CommandProc.LOBYTE(w_nData) != CommonDefine.ERR_FP_CANCEL &&
                     CommandProc.LOBYTE(w_nData) != CommonDefine.ERR_INVALID_OPERATION_MODE &&
                     CommandProc.LOBYTE(w_nData) != CommonDefine.ERR_ALL_TMPL_EMPTY)
		        {
                    Array.Clear(CommandProc.m_pPacketBuffer, 0, CommonDefine.MAX_DATA_LEN + 10);
			        m_clsCmdProc.StartSendThread();
			        return;
		        }
	        }
	        if ((p_nCode == CommonDefine.CMD_ENROLL_CODE) || 
			    (p_nCode == CommonDefine.CMD_CHANGE_TEMPLATE_CODE) )
	        {
		        switch(w_nData)
		        {
		        case CommonDefine.GD_NEED_RELEASE_FINGER:
		        case CommonDefine.GD_NEED_FIRST_SWEEP:
                case CommonDefine.GD_NEED_SECOND_SWEEP:
                case CommonDefine.GD_NEED_THIRD_SWEEP:
                case CommonDefine.ERR_BAD_QUALITY:
                    Array.Clear(CommandProc.m_pPacketBuffer, 0, CommonDefine.MAX_DATA_LEN + 10);
			        m_clsCmdProc.StartSendThread();
			        return;
		        default:
			        break;
		        }
	        }
	        if ((p_nCode == CommonDefine.CMD_ENROLL_ONETIME_CODE) ||
                (p_nCode == CommonDefine.CMD_VERIFY_CODE) ||
		        (p_nCode == CommonDefine.CMD_IDENTIFY_CODE) ||
                (p_nCode == CommonDefine.CMD_IDENTIFY_FREE_CODE))
	        {
		        switch(w_nData)
		        {
		        case CommonDefine.GD_NEED_RELEASE_FINGER:
                    Array.Clear(CommandProc.m_pPacketBuffer, 0, CommonDefine.MAX_DATA_LEN + 10);
			        m_clsCmdProc.StartSendThread();
			        return;
		        default:
			        break;
		        }
	        }

            btnSC_Send.IsEnabled = true;
            cmbSC_Command.IsEnabled = true;
            btnSC_FpCancel.IsEnabled = false;
            btnSC_Send.Focus();

            Array.Clear(CommandProc.m_pPacketBuffer, 0, CommonDefine.MAX_DATA_LEN + 10);
		    m_clsCmdProc.m_bCmdDone = true;
        }

        public string GetErrorMsg(ushort p_nErrorCode)
        {
            string w_ErrMsg;

            switch (CommandProc.LOBYTE(p_nErrorCode))
            {
                case CommonDefine.ERR_VERIFY:
                    w_ErrMsg = "1：1失败";
                    break;
                case CommonDefine.ERR_IDENTIFY:
                    w_ErrMsg = "1：N失败";
                    break;
                case CommonDefine.ERR_EMPTY_ID_NOEXIST:
                    w_ErrMsg = "没有可用编号";
                    break;
                case CommonDefine.ERR_BROKEN_ID_NOEXIST:
                    w_ErrMsg = "没有损坏的模板";
                    break;
                case CommonDefine.ERR_TMPL_NOT_EMPTY:
                    w_ErrMsg = "指纹已经存在";
                    break;
                case CommonDefine.ERR_TMPL_EMPTY:
                    w_ErrMsg = "没有此指纹";
                    break;
                case CommonDefine.ERR_INVALID_TMPL_NO:
                    w_ErrMsg = "错误的指纹编号";
                    break;
                case CommonDefine.ERR_ALL_TMPL_EMPTY:
                    w_ErrMsg = "指纹为空";
                    break;
                case CommonDefine.ERR_INVALID_TMPL_DATA:
                    w_ErrMsg = "错误的指纹数据";
                    break;
                case CommonDefine.ERR_DUPLICATION_ID:
                    w_ErrMsg = "重复指纹 : ";
                    break;
                case CommonDefine.ERR_BAD_QUALITY:
                    w_ErrMsg = "图像质量差";
                    break;
                case CommonDefine.ERR_SMALL_LINES:
                    w_ErrMsg = "图像太小";
                    break;
                case CommonDefine.ERR_TOO_FAST:
                    w_ErrMsg = "手指离开太快";
                    break;
                case CommonDefine.ERR_TIME_OUT:
                    w_ErrMsg = "超时";
                    break;
                case CommonDefine.ERR_GENERALIZE:
                    w_ErrMsg = "创建失败";
                    break;
                case CommonDefine.ERR_NOT_AUTHORIZED:
                    w_ErrMsg = "通讯被加密";
                    break;
                case CommonDefine.ERR_EXCEPTION:
                    w_ErrMsg = "出现异常 ";
                    break;
                case CommonDefine.ERR_MEMORY:
                    w_ErrMsg = "内存出错 ";
                    break;
                case CommonDefine.ERR_INVALID_PARAM:
                    w_ErrMsg = "无效参数";
                    break;
                case CommonDefine.ERR_NO_RELEASE:
                    w_ErrMsg = "请离开手指";
                    break;
                case CommonDefine.ERR_INTERNAL:
                    w_ErrMsg = "内部错误";
                    break;
                case CommonDefine.ERR_FP_CANCEL:
                    w_ErrMsg = "已取消";
                    break;
                case CommonDefine.ERR_INVALID_OPERATION_MODE:
                    w_ErrMsg = "无效的工作模式";
                    break;
                case CommonDefine.ERR_NOT_SET_PWD:
                    w_ErrMsg = "没有设置通讯密码";
                    break;
                case CommonDefine.ERR_FP_NOT_DETECTED:
                    w_ErrMsg = "没有检测到指纹";
                    break;
                case CommonDefine.ERR_ADJUST_SENSOR:
                    w_ErrMsg = "校准传感器失败";
                    break;
                default:
                    w_ErrMsg = "错误";
                    break;
            }

            // Return
            return w_ErrMsg;
        }

        public bool ReadTemplateFile()
        {
	        int				w_nI = 0;
	        ushort			w_nChkSum = 0, w_nCaclChkSum = 0;
            System.IO.FileStream            w_fsTemplate;
            Microsoft.Win32.OpenFileDialog  w_cfdOpenTemplate = new Microsoft.Win32.OpenFileDialog();

            w_cfdOpenTemplate.DefaultExt = ".fpt";
            w_cfdOpenTemplate.Filter = "Template File(*.fpt)|*.fpt";

            if (w_cfdOpenTemplate.ShowDialog() == true)
	        {
                w_fsTemplate = new System.IO.FileStream(w_cfdOpenTemplate.FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
                if (w_fsTemplate.Length != CommonDefine.GD_RECORD_SIZE)
                {
                    MessageBox.Show("错误的模板数据 !", "Open Template", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    return false;
                }
                w_fsTemplate.Read(m_pTemplateData, 0, CommonDefine.GD_RECORD_SIZE);
                w_fsTemplate.Close();

                // Check CheckSum
			    for (w_nI = 0; w_nI < CommonDefine.GD_TEMPLATE_SIZE - 2 ; w_nI ++)
                {
				    w_nChkSum += m_pTemplateData[w_nI];
			    }
                w_nCaclChkSum = (ushort)((m_pTemplateData[CommonDefine.GD_TEMPLATE_SIZE - 1] << 8) + m_pTemplateData[CommonDefine.GD_TEMPLATE_SIZE - 2]);
			    if (w_nChkSum != w_nCaclChkSum)
			    {
                    MessageBox.Show("错误的模板数据 !", "Open Template", MessageBoxButton.OK, MessageBoxImage.Exclamation);
				    return false;
			    }

			    return true;
	        }
	
	        return false;
        }

        public bool ReadTemplateFile2()
        {
            int w_nI = 0;
            ushort w_nChkSum = 0, w_nCaclChkSum = 0;
            System.IO.FileStream w_fsTemplate;
            Microsoft.Win32.OpenFileDialog w_cfdOpenTemplate = new Microsoft.Win32.OpenFileDialog();

            w_cfdOpenTemplate.DefaultExt = ".fpt";
            w_cfdOpenTemplate.Filter = "Template File(*.fpt)|*.fpt";

            if (w_cfdOpenTemplate.ShowDialog() == true)
            {
                w_fsTemplate = new System.IO.FileStream(w_cfdOpenTemplate.FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
                if (w_fsTemplate.Length != CommonDefine.GD_RECORD_SIZE)
                {
                    MessageBox.Show("错误的模板数据 !", "Open Template", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    return false;
                }
                w_fsTemplate.Read(m_pTemplateData2, 0, CommonDefine.GD_RECORD_SIZE);
                w_fsTemplate.Close();

                // Check CheckSum
                for (w_nI = 0; w_nI < CommonDefine.GD_TEMPLATE_SIZE - 2; w_nI++)
                {
                    w_nChkSum += m_pTemplateData2[w_nI];
                }
                w_nCaclChkSum = (ushort)((m_pTemplateData2[CommonDefine.GD_TEMPLATE_SIZE - 1] << 8) + m_pTemplateData2[CommonDefine.GD_TEMPLATE_SIZE - 2]);
                if (w_nChkSum != w_nCaclChkSum)
                {
                    MessageBox.Show("错误的模板数据 !", "Open Template", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    return false;
                }

                return true;
            }

            return false;
        }

        public bool WriteTemplateFile(byte[] p_pTemplate)
        {
	        System.IO.FileStream            w_fsTemplate;
            Microsoft.Win32.SaveFileDialog  w_cfdSaveTemplate = new Microsoft.Win32.SaveFileDialog();
            
            w_cfdSaveTemplate.DefaultExt = ".fpt";
            w_cfdSaveTemplate.Filter = "Template File(*.fpt)|*.fpt";

            if (w_cfdSaveTemplate.ShowDialog() == true)
            {
                w_fsTemplate = new System.IO.FileStream(w_cfdSaveTemplate.FileName, System.IO.FileMode.Create, System.IO.FileAccess.Write);
                w_fsTemplate.Write(p_pTemplate, 0, CommonDefine.GD_RECORD_SIZE);
                w_fsTemplate.Close();
			    return true;
	        }

            return false;
        }

        public bool ReadImage(byte[] p_pImage)
        {
            Microsoft.Win32.OpenFileDialog w_cfdOpenImage = new Microsoft.Win32.OpenFileDialog();

            w_cfdOpenImage.DefaultExt = ".bmp";
            w_cfdOpenImage.Filter = "Bitmap File(*.bmp)|*.bmp";

            if (w_cfdOpenImage.ShowDialog() == true)
            {
                // Create a new bitmap.
                Bitmap w_bmpImg = new Bitmap(w_cfdOpenImage.FileName);

                // Lock the bitmap's bits.  
                Rectangle w_rtImg = new Rectangle(0, 0, w_bmpImg.Width, w_bmpImg.Height);
                BitmapData w_bmpData = w_bmpImg.LockBits(w_rtImg, ImageLockMode.ReadWrite, w_bmpImg.PixelFormat);

                // Get the address of the first line.
                IntPtr w_ptrImg = w_bmpData.Scan0;

                // Copy the RGB values into the array.
                Marshal.Copy(w_ptrImg, CommandProc.g_pImageBuf, 0, w_bmpImg.Width * w_bmpImg.Height);
                CommandProc.g_nImageWidth = w_bmpImg.Width;
                CommandProc.g_nImageHeight = w_bmpImg.Height;

                w_bmpImg.UnlockBits(w_bmpData);
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool WriteBMP(string filename, byte[] p_pbImageData, int p_nWidth, int p_nHeight)
        {
            // Create the 8bpp indexed bitmap 
            Bitmap w_bmpImg = new Bitmap(p_nWidth, p_nHeight, PixelFormat.Format8bppIndexed);
            ColorPalette w_cpImg = w_bmpImg.Palette;
            IntPtr w_ptrBuf;
            int i;

            for (i = 0; i < 256; i++)
                w_cpImg.Entries[i] = Color.FromArgb(255, i, i, i);
            w_bmpImg.Palette = w_cpImg;

            var w_rtBounds = new Rectangle(0, 0, p_nWidth, p_nHeight);
            BitmapData w_bmpData = w_bmpImg.LockBits(w_rtBounds,
                                            ImageLockMode.WriteOnly,
                                            w_bmpImg.PixelFormat);

            w_ptrBuf = w_bmpData.Scan0;
            Marshal.Copy(p_pbImageData, 0, w_ptrBuf, p_nWidth * p_nHeight);
            w_bmpImg.UnlockBits(w_bmpData);

            w_bmpImg.Save(filename);

            return true;
        }

        private void btnSC_FpCancel_Click(object sender, RoutedEventArgs e)
        {
            btnSC_FpCancel.IsEnabled = false;
            Run_FpCancel();
        }

        private void SZHostDlg_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            CommandProc.g_bCloseApp = true;
        }
    }
}
